﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TsTreeTimeSeries.tstree;

namespace TsTreeTimeSeries.node
{
    class Node
    {
        public int nodeId = 0;
        public Entry sumEntry = null;
        public Entry[] entries = null;
        public int[] ids = null;
        public int level;
        public int entryCount;
        public int parentNodeId;
        public Node(int nodeId, int level, int maxNodeEntries)
        {
            this.nodeId = nodeId;
            this.level = level;
            entries = new Entry[maxNodeEntries];
            ids = new int[maxNodeEntries];
        }

        public Entry getEntry(int index)
        {
            if (index < entryCount)
            {
                return entries[index];
            }
            return null;
        }

        public void addEntryNoCopy(Entry r, int id)
        {
            ids[entryCount] = id;
            entries[entryCount] = r;
            entryCount++;
            if (sumEntry == null)
            {
                sumEntry = r.copy();
            }
            else
            {
                sumEntry.add(r);
            }
        }


        public void addEntry(Entry r, int id)
        {
            ids[entryCount] = id;
            entries[entryCount] = r.copy();
            entryCount++;
            if (sumEntry == null)
            {
                sumEntry = r.copy();
            }
            else
            {
                sumEntry.add(r);
            }
        }

        public void reorganize(TSTree rtree)
        {
            int countdownIndex = rtree.maxNodeEntries - 1;
            for (int index = 0; index < entryCount; index++)
            {
                if (entries[index] == null)
                {
                    while (entries[countdownIndex] == null && countdownIndex > index)
                    {
                        countdownIndex--;
                    }
                    entries[index] = entries[countdownIndex];
                    ids[index] = ids[countdownIndex];
                    entries[countdownIndex] = null;
                }
            }
        }

        // tinh toan lai findEntry theo mindist
        public int findEntry(Entry r, int id)
        {
            for (int i = 0; i < entryCount; i++)
            {
                if (id == ids[i] && r.Equals(entries[i]))
                {
                    return i;
                }
            }
            return -1;
        }

        public void deleteEntry(int i, int minNodeEntries)
        {
            int lastIndex = entryCount - 1;
            Entry deletedRectangle = entries[i];
            entries[i] = null;
            if (i != lastIndex)
            {
                entries[i] = entries[lastIndex];
                ids[i] = ids[lastIndex];
                entries[lastIndex] = null;
            }
            entryCount--;

            // if there are at least minNodeEntries, adjust the MBR.
            // otherwise, don't bother, as the Node<T> will be 
            // eliminated anyway.
            if (entryCount >= minNodeEntries)
            {
                recalculateMBR(deletedRectangle);
            }
        }

        public void recalculateMBR(Entry deletedRectangle)
        {
            if (sumEntry.edgeOverlaps(deletedRectangle))
            {
                sumEntry.set(entries[0].lowerBound, entries[0].upperBound);

                for (int i = 1; i < entryCount; i++)
                {
                    sumEntry.add(entries[i]);
                }
            }
        }

       

        public bool isLeaf()
        {
            return (level == 1);
        }

    }
}
